---@class Battle.EventManager
EventManager = Battle.CreateClass("EventManager")
Battle.EventManager = EventManager
local this = EventManager
function EventManager:OnCreate()
    this.eventListeners = {};
end
function this.getIns()
    return this;
end

function this.addEventListener( eventId, fighterId, fightEventListener)
    ---@type table<number, table<number, table<string, IFightEventListener>>>
    local eventListeners = this.eventListeners;

    local map = nil;
    if (not eventListeners[eventId]) then
        map = {};
        eventListeners[eventId] = map;
    else
        map = eventListeners[eventId];
    end

    local events = nil;
    if (not map[fighterId]) then
        events = {};
        map[fighterId] = events;
    else
        events = map[fighterId];
    end
    events[fightEventListener:getId()] = fightEventListener;
end

function this.removeEventListener( eventId, fighterId, fightEventListenerId)
    ---@type table<number, table<number, table<string, IFightEventListener>>>
    local eventListeners = this.eventListeners;
    if (not eventListeners[eventId]) then
        return ;
    end
    local map = eventListeners[eventId];
    if (not map[fighterId]) then
        return ;
    end
    local events = map[fighterId];
    events[fightEventListenerId] = nil;
end
--触发这个时机所有英雄的buff
function this.notifyEventListenerAll (eventId,fighterId, ...)
    ---@type table<number, table<number, table<string, IFightEventListener>>>
    local eventListeners = this.eventListeners;
    if (not eventListeners[eventId]) then
        return ;
    end
    local map = eventListeners[eventId];
    for i, v in pairs(map) do
        local eventsMap = v;
        if i ~= fighterId then
            local events = {};
            addTable(events, eventsMap);
            this.sort(events)
            for k, fightEventListener in pairs(events) do
                fightEventListener:notify(eventId, ...);
            end

        end
    end
end

function this.notifyEventListener( eventId, fighterId, ...)
    ---@type table<number, table<number, table<string, IFightEventListener>>>
    local eventListeners = this.eventListeners;
    if (not eventListeners[eventId]) then
        return ;
    end
    local map = eventListeners[eventId];
    if (not map[fighterId]) then
        return ;
    end
    local eventsMap = map[fighterId];

    local events = {};
    addTable(events, eventsMap);
    this.sort(events)
    for i, fightEventListener in pairs(events) do
        fightEventListener:notify(eventId, ...);
    end
end

function this.notifyEventByCampId( eventId, campId, ...)
    local GrassList = Battle.ActorManager.GetActorListByCamp(campId)
    for i, entity in pairs(GrassList) do
        this.notifyEventListener(eventId, entity.id)
    end
end

function this.sort(events)
    if (events == nil or table.getn(events) < 2) then
        return ;
    end
    table.sort(events,function(o1, o2)
        return o2:priority() > o1:priority();
    end);
    --		BubbleSortUtil.bubble(events, new Comparator<IFightEventListener>() {
    --			@Override
    --			public int compare(IFightEventListener o1, IFightEventListener o2) {
    --				return o2.priority() - o1.priority();
    --			}
    --		});
end

--function this.addDelayedEvent( frame, event)
--    local list = {};
--    if (fight.events[frame]) then
--        list = fight.events[frame];
--    else
--        list = {};
--        fight.events[frame] = list;
--    end
--    table.insert(list, event);
--end

function this.OnDestroy()
    this.eventListeners = {};
end 